package com.nixus.raop;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import javax.jmdns.ServiceListener;

import org.apache.http.conn.util.InetAddressUtils;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.ToggleButton;

import com.nixus.raop.R;
import com.nixus.raop.core.PropertyManager;
import com.nixus.raop.core.ServiceContextImpl;
import com.nixus.raop.core.ServicesManager;
import com.nixus.raop.player.PlayerImpl;
import com.nixus.raop.speaker.airport.Finder;
import com.nixus.raop.speaker.airport.SpeakerImpl;
import com.nixus.raop.zeroconf.ZeroConfFactory;

public class MainActivity extends Activity implements ServicesManager,OnClickListener {
	/** Called when the activity is first created. */

	public static List<ServiceContextImpl> contexts;
	public static PropertyManager pm;

	protected ServiceListener listener;

	protected static LibraryAdapter discoveredDevicesAdapter;

	public final static String HOST_NAME = "tsthostname";

	private PlayerImpl pl;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		ToggleButton tb = (ToggleButton) findViewById(R.id.toggleButton1);
		tb.setOnClickListener(this);
		
		ListView discoveredDevicesList = (ListView)findViewById(R.id.list);
		discoveredDevicesAdapter = new LibraryAdapter(this);
		discoveredDevicesList.setAdapter(discoveredDevicesAdapter);


		this.startDeviceDiscovery();

	}

	private void startDeviceDiscovery() {
		contexts = new CopyOnWriteArrayList<ServiceContextImpl>();

		pm =  new PropertyManager();
		pm.init();

		ServiceContextImpl sczcf = new ServiceContextImpl(new ZeroConfFactory(), "zeroconffactory",pm,this);
		sczcf.putProperty("implementation", "jmdns");
		sczcf.putProperty("bind", getLocalIpAddress());
		sczcf.putProperty("hostname", HOST_NAME);
		this.addServiceContext(sczcf);
		sczcf.start();


		ServiceContextImpl scaf = new ServiceContextImpl(new Finder(), "airportfactory",pm,this);
		this.addServiceContext(scaf);
		scaf.start();

		pl = new PlayerImpl();
		ServiceContextImpl scpl = new ServiceContextImpl(pl, "main",pm,this);
		this.addServiceContext(scpl);
		scpl.start();


		//		try {
		//			Thread.sleep(30000);
		//		} catch (InterruptedException e) {
		//			// TODO Auto-generated catch block
		//			e.printStackTrace();
		//		}
		//        
		//		pl.play();
	}

	public void addServiceContext(final ServiceContextImpl context) {
		contexts.add(context);
		
		if (context.getService() instanceof SpeakerImpl){
			runOnUiThread(new Runnable() {
				public void run() {
					discoveredDevicesAdapter.notifyFound(context);
					discoveredDevicesAdapter.notifyDataSetChanged();
				}
			});

		}
	}

	public void removeServiceContext(ServiceContextImpl context) {
		contexts.remove(context);
		pm.remove(context.getProperty("name"));
	}

	public Iterator<ServiceContextImpl> getServices() {
		return contexts.iterator();
	}

	public String getLocalIpAddress() {
		try {
			for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
				NetworkInterface intf = en.nextElement();
				for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
					InetAddress inetAddress = enumIpAddr.nextElement();
					if (!inetAddress.isLoopbackAddress() && InetAddressUtils.isIPv4Address(inetAddress.getHostAddress())) {
						System.out.println("Found addr = " + inetAddress.getHostAddress().toString());
						return inetAddress.getHostAddress().toString();
					}
				}
			}
		} catch (SocketException ex) {
			Log.e("MainPage", ex.toString());
		}
		return null;
	}


	public class LibraryAdapter extends BaseAdapter {

		protected Context context;
		protected LayoutInflater inflater;

		public View footerView;

		protected List<ServiceContextImpl> known = new LinkedList<ServiceContextImpl>();

		public LibraryAdapter(Context context) {
			this.context = context;
			this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		}

		public void notifyFound(ServiceContextImpl context) {
			known.add(context);
		}

		public Object getItem(int position) {
			return known.get(position);
		}

		public boolean hasStableIds() {
			return true;
		}

		public int getCount() {
			return known.size();
		}

		public long getItemId(int position) {
			return position;
		}


		public View getView(int position, View convertView, ViewGroup parent) {

			final String airportName = ((ServiceContextImpl)this.getItem(position)).getProperty("name").replace("speaker.airport.", "");
			final String airportAddress = ((ServiceContextImpl)this.getItem(position)).getProperty("host");
			
			LayoutInflater inflater = (LayoutInflater) context
					.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

			View rowView = inflater.inflate(R.layout.device_list_element, parent, false);
			TextView textView = (TextView) rowView.findViewById(R.id.textView1);
			ToggleButton tb = (ToggleButton) rowView.findViewById(R.id.toggleButton1);

			textView.setText(airportName + " (" +airportAddress+")");

			//tb.setOnClickListener((OnClickListener) this);

			tb.setOnClickListener(new OnClickListener() {
				
				public void onClick(View v) {
					System.out.println("Clicked ");
//					
//							((Speaker) known.get(0).getService()).setPlayer(pl);
//							pl.addSpeaker((Speaker) known.get(0).getService());
					String[] args = new String[3];
					args[0] = "raop-play";
					args[1] = airportAddress;
					args[2] = "/sdcard/gio.wav";
//					"raop-play",
//					"192.168.1.1",
//					"/sdcard/gio.wav"};
					System.out.println(raopPlayNoArg());
				}
			});
			
			return rowView;

		}


	}


	public void onClick(View arg0) {
		String[] args = new String[3];
		args[0] = "test";
		args[1] = "test";
		args[2] = "test";
		System.out.println(raopPlay(args));
	}

	
    /* A native method that is implemented by the
     * 'hello-jni' native library, which is packaged
     * with this application.
     */
    public native String  raopPlay(String[] args);
    public native String  raopPlayNoArg();
	
    static {
    	System.loadLibrary("ssl");
    	System.loadLibrary("crypto");
    	System.loadLibrary("samplerate");
        System.loadLibrary("raop-play");
    }

}